#include <iostream>
#include <vector>
using namespace std;

class Main {
	typedef long long LL;

	int n, m, maxs;

	int get(int s, int j)
	{
		return (s >> j) & 1;
	}

	int set(int s, int j, int v)
	{
		return v == 1 ? s | (1 << j) : (s & (~(1 << j)));
	}

    public:
	Main(int h, int w) : n(h), m(w), maxs(1 << w)
	{
	}

	LL ways_ud_sp()
	{
		vector<LL> dp(1 << m, 0), new_dp(dp);
		dp[(1 << m) - 1] = 1;

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				fill(new_dp.begin(), new_dp.end(), 0);
				for (int s = 0; s < maxs; s++) {
					if (dp[s] == 0) {
						continue;
					}
					if (get(s, j) == 1) {
						if (j > 0 && get(s, j - 1) == 0) {
							int ns = set(s, j, 1) | set(s, j - 1, 1);
							new_dp[ns] += dp[s];
							new_dp[set(s, j, 0)] += dp[s];
						} else {
							new_dp[set(s, j, 0)] += dp[s];
						}
					} else {
						new_dp[set(s, j, 1)] += dp[s];
					}
				}
				dp.swap(new_dp);
			}
		}
		return dp[(1 << m) - 1];
	}

	LL ways_ud()
	{
		vector<vector<LL>> dp(m + 2, vector<LL>(1 << m, 0));
		dp[0][(1 << m) - 1] = 1;

		for (int i = 0; i <= n; i++) {
			for (int j = 0; j < m; j++) {
				fill(dp[j + 1].begin(), dp[j + 1].end(), 0);
				for (int s = 0; s < maxs; s++) {
					if (dp[j][s] == 0) {
						continue;
					}
					if (get(s, j) == 1) {
						if (j > 0 && get(s, j - 1) == 0) {
							int ns = set(s, j, 1) | set(s, j - 1, 1);
							dp[j + 1][ns] += dp[j][s];
							dp[j + 1][set(s, j, 0)] += dp[j][s];
						} else {
							dp[j + 1][set(s, j, 0)] += dp[j][s];
						}
					} else {
						dp[j + 1][set(s, j, 1)] += dp[j][s];
					}
				}
			}
			dp[0].swap(dp[m]);
		}
		return dp[0][0];
	}

	LL ways()
	{
		vector<vector<LL>> dp(m + 1, vector<LL>(1 << m, 0));
		fill(dp[m].begin(), dp[m].end(), 1);

		for (int i = n - 1; i >= 0; i--) {
			for (int j = m - 1; j >= 0; j--) {
				for (int s = 0; s < maxs; s++) {
					LL ans = 0;
					if (get(s, j) == 1) {
						ans = dp[j + 1][set(s, j, 0)];
					} else {
						if (i + 1 < n) {
							ans = dp[j + 1][set(s, j, 1)];
						}
						if (j + 1 < m && get(s, j + 1) == 0) {
							ans += dp[j + 2][s];
						}
					}
					dp[j][s] = ans;
				}
			}
			dp[m].swap(dp[0]);
		}

		return dp[m][0];
	}

	LL ways_sp()
	{
		vector<LL> dp(1 << m, 1);
		vector<LL> dp_n(1 << m, 1);
		vector<LL> new_dp(1 << m, 0);

		for (int i = n - 1; i >= 0; i--) {
			for (int j = m - 1; j >= 0; j--) {
				for (int s = 0; s < maxs; s++) {
					LL ans = 0;
					if (get(s, j) == 1) {
						ans = dp[set(s, j, 0)];
					} else {
						if (i + 1 < n) {
							ans = dp[set(s, j, 1)];
						}
						if (j + 1 < m && get(s, j + 1) == 0) {
							ans += dp_n[s];
						}
					}
					new_dp[s] = ans;
				}
				dp.swap(dp_n);
				dp.swap(new_dp);
			}
		}

		return dp[0];
	}

	LL ways(int i, int j, int s, vector<vector<vector<int>>> &dp)
	{
		if (i == n) {
			return 1;
		}
		if (j == m) {
			return ways(i + 1, 0, s, dp);
		}

		if (dp[i][j][s] != -1) {
			return dp[i][j][s];
		}
		LL ans = 0;
		if (get(s, j) == 1) {
			ans = ways(i, j + 1, set(s, j, 0), dp);
		} else {
			if (i + 1 < n) {
				ans = ways(i, j + 1, set(s, j, 1), dp);
			}
			if (j + 1 < m && get(s, j + 1) == 0) {
				ans += ways(i, j + 2, set(s, j, 0), dp);
			}
		}
		return dp[i][j][s] = ans;
	}

	LL ways_up(int i, int j, int s)
	{
		if (i == 0) {
			return s == (1 << m) ? 1 : 0;
			return 1;
		}
		if (j < 0) {
			return ways_up(i - 1, m, s);
		}

                

		LL ans = 0;
		if (get(s, j) == 1) {
			ans += ways_up(i - 1, j - 1, set(s, j, 0));
			if (j > 0) {
				ans += ways_up(i - 1, j - 2, set(s, j, 0) | set(s, j - 1, 0));
			}
		} else {
			ans += ways_up(i - 1, j - 1, set(s, j, 1));
		}

		return ans;
	}
};

int main()
{
	int h = 0, w = 0;
	while (cin >> h >> w) {
		if (h == 0 && w == 0) {
			break;
		}
		Main app(h, w);
		// vector<vector<vector<int>>> dp(h, vector<vector<int>>(w, vector<int>(1 << w, -1)));
		// cout << app.ways(0, 0, 0, dp) << endl;
		cout << app.ways_up(h, w, 1 << w) << endl;
	}
	return 0;
}
/*
1 2
0 0
*/